/*******************************************************************************
 * The MOSES project, model based software engineering of networked embedded systems.
 * 
 * Copyright (C) 2010-2013, University of Applied Sciences Wildau,
 * Telematics Research Group, http://www.tm.th-wildau.de/research-group
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses>.
 * 
 * Contributors:
 *     University of Applied Sciences Wildau - initial API and implementation
 * 
 * If you are interested in a commercial license please contact us via 
 * e-mail: ralf.vandenhouten@th-wildau.de.
 ******************************************************************************/
package de.thwildau.tm.moses.thrift.scoping;

import static org.eclipse.xtext.util.Strings.isEmpty;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.mwe2.language.mwe2.Import;
import org.eclipse.xtext.scoping.impl.ImportUriResolver;

import com.google.inject.Inject;

import de.thwildau.tm.moses.thrift.thrift.Include;

/**
 * This implementation mimics how Thrift understands URIs of imported files. For example, the URI
 * "platform:/resource/shared.thrift" is understood by EMF but not by Thrift. The URI in the thrift file needs
 * to be simply "shared.thrift" for the Thrift compiler to understand it.
 * <p>
 * This {@link ImportUriResolver} adds "platform:/resource" to any URI if is not specified, so EMF can find
 * the imported resource.
 * </p>
 * 
 * @author Thomas Kistel
 * @version $Revision: 759 $
 */
public class ThriftImportUriResolver extends ImportUriResolver {

    @Inject
    private FileResolverStrategies resolvers;


    /**
     * If the given {@code EObject} is a <code>{@link Import}</code>, this method will add
     * "platform:/resource" to the URI of such import if not specified already.
     * 
     * @param from the given element to resolve.
     * @return the {@code String} representation of the given object's {@code URI}.
     */
    @Override
    public String apply(EObject from) {
        if (from instanceof Include) {
            Include anImport = (Include)from;
            anImport.setImportURI(resolveImportUri(anImport));
        }
        return super.apply(from);
    }

    private String resolveImportUri(Include anImport) {
        String importURI = anImport.getImportURI();
        return resolveUri(importURI, anImport.eResource());
    }

    public String resolveUri(String importUri, Resource declaringResource) {
        if (hasScheme(importUri))
            return importUri;
        String resolved = getResolverStrategy().resolveUri(importUri, declaringResource.getURI());
        return (resolved == null) ? importUri : resolved;
    }

    /**
     * Tests if the given <code>importUri</code> already has a Scheme. Those Uri's can be skipped.
     */
    private boolean hasScheme(String importUri) {
        String scheme = URI.createURI(importUri).scheme();
        return !isEmpty(scheme);
    }

    private FileResolverStrategy getResolverStrategy() {
        return resolvers.strategyFor(PathResolvingType.SINGLE_DIRECTORY);
    }
}
